package minformer;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;


public class ScrWeatherScreen extends Canvas implements CommandListener, Runnable
{
	private static final int RUN_STATE_LOADING_IMAGE = 10000;
	private int runState;
	private Command cmdRefresh = new Command("Обновить", Command.ITEM, 1);
	private Command cmdCancelBackImage = new Command("Убрать фон", Command.ITEM, 4);
	private Command cmdSelectScreen = new Command("Фон...", Command.SCREEN, 2);
	private Command cmdOptions = new Command("Настройки...", Command.SCREEN, 3);
	private Command cmdMinimize = new Command("Свернуть", Command.SCREEN, 4);
	private Display display;
	private Hashtable results;
	private FileBrowser fileBrowser;
	private Image backImage;
	private Image Phenomena1;
	private Image Phenomena2;
	
	private Font bigBoldFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_LARGE);
	private Font bigFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_LARGE);
	private Font smallFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_SMALL);
	private Font boldFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_MEDIUM);
	private Font mediumFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);

	private int layer = smallFont.getHeight()/2;
	private int imgWidth = 0;
	private int imgHeight = 0;

	public ScrWeatherScreen(Display display)
	{
		this.display = display;
		setFullScreenMode(false);
		addCommand(cmdRefresh);
		addCommand(cmdSelectScreen);
		addCommand(cmdOptions);
		addCommand(cmdMinimize);
		addCommand(cmdCancelBackImage);
		setCommandListener(this);
		loadBackImage();
	}
	
	public void run()
	{
		switch (runState)
		{
		case RUN_STATE_LOADING_IMAGE:
			FileConnection fileConnection = null;
			InputStream result = null;
			
			try
			{
				fileConnection = (FileConnection) Connector.open("file://"+Options.backGrndImage,Connector.READ);
				result = fileConnection.openInputStream();
				backImage = null;
				backImage = Image.createImage(result);
			}
			catch (OutOfMemoryError me)
			{
				System.gc();
				me.printStackTrace();
				backImage = null;
			}
			catch (Exception e)
			{
				e.printStackTrace();
				backImage = null;
			}
			finally
			{
				if (result != null) try { result.close(); } catch (Exception e) {}
				if (fileConnection != null) try { fileConnection.close(); } catch (Exception e) {}
			}
			repaint();
			break;
		}
	}
	
	public void loadPhenomenaImage(String imgName1, String imgName2)
	{
		try
		{
		    Phenomena1 = null;
		    Phenomena1 = Image.createImage ("/" + imgName1 + ".png");
		    imgWidth = Phenomena1.getWidth();
		    imgHeight = Phenomena1.getHeight();
		} catch (Exception e) {}
		try {
		    Phenomena2 = null;
		    Phenomena2 = Image.createImage ("/" + imgName2 + ".png");
		} catch (Exception e) {}
	}
	
	private void loadBackImage()
	{
		if ((Options.backGrndImage == null) || (Options.backGrndImage.length() == 0))
		{
			backImage = null;
			return;
		}
		
		runState = RUN_STATE_LOADING_IMAGE;
		new Thread(this).start();
	}
	
	private int showDayWeather(Vector data, int start, int count, Graphics g, int x, int y)
	{
		String date = (String)data.elementAt(start);
		g.setFont(smallFont);
		g.drawString(date, x + imgWidth + layer/2, y, Graphics.TOP|Graphics.LEFT);
		y += layer*2;

		String dayTemp = (String)data.elementAt(start+1);
		g.setFont(bigBoldFont);
		g.drawString(dayTemp, x + imgWidth + layer/2, y, Graphics.TOP|Graphics.LEFT);
		y += bigBoldFont.getHeight();
		Font fnt;
		String line;
		for (int i = 2; i < count; i++)
		{
			fnt = (i <= 2) ? boldFont : smallFont;
			g.setFont(fnt);
			line = (String)data.elementAt(start+i);
			g.drawString(line, x, y, Graphics.TOP|Graphics.LEFT);
			y += fnt.getHeight();
		}
		
		return y;
	}
	
	static public int getInverseColor(int color)
	{
		int r = (color & 0xFF);
		int g = ((color & 0xFF00) >> 8);
		int b = ((color & 0xFF0000) >> 16);
		return ((r+g+b) > 512) ? 0 : 0xFFFFFF;
	}
	
	private void paint(Vector data, int count, Graphics g, int capColor, int textColor, int xOffset, int yOffset)
	{
		String cityName = (data == null) ? "Gismeteo.ru" : (String)results.get("city");
		
		int y = (Options.yPos + (Options.onlyOneDay ? 2 : 0)) * layer + yOffset;
		int x = layer;
		
		g.setColor(capColor);
		g.setFont(bigBoldFont);
		g.drawString(cityName, x+xOffset, y, Graphics.TOP|Graphics.LEFT);
		y += bigBoldFont.getHeight()+layer/2;

		if (results == null) return;
		
		int dataSize = data.size();
		g.setColor(textColor);
		if (Phenomena1 != null)
		    g.drawImage(Phenomena1, x, y, Graphics.LEFT | Graphics.TOP);

		y = showDayWeather(data, 0, dataSize/2, g, x+xOffset, y);
		if (!Options.onlyOneDay) {
		    y += (imgHeight + layer)/2;
		    if (Phenomena2 != null)
			g.drawImage(Phenomena2, x, y, Graphics.LEFT | Graphics.TOP);
		    showDayWeather(data, dataSize/2, dataSize/2, g, x+xOffset, y);	
		}
	}
	
	protected void paint(Graphics g)
	{
		Vector data = null;
		
		if (results != null)
		{
			data = new Vector();
			
			data.addElement((String)results.get("d1"));
			
			data.addElement((String)results.get("d1t")+"°C");
			
			data.addElement("ночью: "+(String)results.get("n1t")+"°C");

//			data.addElement((String)results.get("d1o"));
			
			if (Options.viewMode == Options.VIEW_MODE_FULL)
				data.addElement(results.get("w1")+", "+(String)results.get("p1")+"мм, "+(String)results.get("h1")+"%");

			data.addElement((String)results.get("d2"));

			data.addElement((String)results.get("d2t")+"°C");

			data.addElement("ночью: "+(String)results.get("n2t")+"°C");

//			data.addElement((String)results.get("d2o"));

			if (Options.viewMode == Options.VIEW_MODE_FULL)
				data.addElement(results.get("w2")+", "+(String)results.get("p2")+"мм, "+(String)results.get("h2")+"%");
		}
		
		if (backImage == null)
		{
			g.setColor(Options.backColor);
			g.fillRect(0, 0, getWidth(), getHeight());
		}
		else
		{
			int scrWidth = getWidth();
			int scrHeight = getHeight();
			int imgWidth = backImage.getWidth();
			int imgHeight = backImage.getHeight();
			for (int x = 0; x < scrWidth; x += imgWidth)
				for (int y = 0; y < scrHeight; y += imgHeight)
					g.drawImage(backImage, x, y, Graphics.LEFT|Graphics.TOP);
		}
		
		if (Options.textBorder) {
		    int borderColor = getInverseColor(Options.textColor);
		    for (int x = -1; x <= 1; x++)
			    for (int y = -1; y <= 1; y++)
				    paint(data, 2, g, borderColor, borderColor, x, y);
		}
		paint(data, 2, g, Options.textColor, Options.textColor, 0, 0);
	}
	
	public void showResults(Hashtable results)
	{
		this.results = results;
		repaint();
	}
	
	public void commandAction(Command c, Displayable d)
	{
		if (c == cmdRefresh)
		{
				ScrWeather.refresh();
		}
		else if (c == cmdOptions)
		{
				ScrWeather.showOptions();
		}
		else if (c == cmdSelectScreen)
		{
				fileBrowser = new FileBrowser();
				fileBrowser.browse(null, this, false, display);
		}
		else if (c == FileBrowser.cmdCancel)
		{
			fileBrowser = null;
			display.setCurrent(this);
		}
		else if (c == cmdMinimize)
		{
			ScrWeather.setMinimized(true);
		}
		else if (c == FileBrowser.cmdSelect)
		{
				display.setCurrent(this);
				Options.backGrndImage = fileBrowser.getValue();
				Options.save();
				try { fileBrowser.close(); } catch (Exception e) {}
				fileBrowser = null;
				loadBackImage();
				repaint();
		}
		else if (c == cmdCancelBackImage)
		{
				Options.backGrndImage = null;
				Options.save();
				backImage = null;
				repaint();
		} 
	}

}
